from machine import FPIOA, I2C
import time

HARD_I2C = True

# 使用硬件 I2C
if HARD_I2C:
    fpioa = FPIOA()
    fpioa.set_function(44, FPIOA.IIC3_SCL)
    fpioa.set_function(45, FPIOA.IIC3_SDA)
    i2c = I2C(3, freq=100 * 1000)  # 降低频率至 100kHz
    print(i2c.scan())
else:
    # 使用软 I2C
    i2c = I2C(5, scl=11, sda=12, freq=100 * 1000)  # 降低频率
    print(i2c.scan())

# SSD1306 I2C 地址（常见值：0x3C 或 0x3D）
OLED_I2C_ADDR = 0x3C

# 向 SSD1306 发送命令的函数
def send_command(command):
    # 0x00 表示发送命令（而非数据）
    i2c.writeto(OLED_I2C_ADDR, bytearray([0x00, command]))

# 向 SSD1306 发送数据（用于像素值）的函数
def send_data(data):
    # 0x40 表示发送数据（而非命令）
    i2c.writeto(OLED_I2C_ADDR, bytearray([0x40] + data))

# 增强版 SSD1306 初始化序列
def oled_init():
    # 重置序列
    time.sleep_ms(100)  # 启动延时

    send_command(0xAE)  # 关闭显示
    send_command(0xD5)  # 设置显示时钟分频比/振荡器频率
    send_command(0x80)  # 默认设置

    send_command(0xA8)  # 设置多路复用率
    send_command(0x3F)  # 1/64 占空比（64MUX）

    send_command(0xD3)  # 设置显示偏移
    send_command(0x00)  # 无偏移

    send_command(0x40)  # 设置起始行为 0

    send_command(0x8D)  # 电荷泵设置
    send_command(0x14)  # 使能电荷泵

    send_command(0x20)  # 内存寻址模式
    send_command(0x00)  # 水平寻址模式

    send_command(0xA1)  # 段重映射（0xA1 反向，0xA0 正常），若仍颠倒可尝试换回 0xA0
    send_command(0xC8)  # COM 输出扫描方向（0xC8 反向，0xC0 正常），若仍颠倒可尝试换回 0xC0

    send_command(0xDA)  # COM 引脚硬件配置
    send_command(0x12)  # 替代 COM 引脚配置，禁用左右重映射

    send_command(0x81)  # 对比度控制
    send_command(0xCF)  # 中等对比度

    send_command(0xD9)  # 设置预充电周期
    send_command(0xF1)  # 阶段 1: 15 个 DCLK，阶段 2: 1 个 DCLK

    send_command(0xDB)  # 设置 VCOMH 取消选择级别
    send_command(0x40)  # ~0.77*Vcc

    send_command(0xA4)  # 整个显示打开，恢复到 RAM 内容显示
    send_command(0xA6)  # 设置正常显示（0xA6 正常，0xA7 反转）

    send_command(0xAF)  # 打开显示
    time.sleep_ms(100)  # 初始化完成延时

# 修正后的清屏函数
def oled_clear():
    for page in range(0, 8):  # 64 像素高屏幕的 8 页
        send_command(0xB0 + page)  # 设置页起始地址（0xB0 到 0xB7）
        send_command(0x00)  # 设置低列地址
        send_command(0x10)  # 设置高列地址
        send_data([0x00] * 128)  # 填充 0x00 以熄灭所有像素
    time.sleep_ms(50)  # 清屏延时

# 测试图案函数
def test_pattern():
    """显示测试图案（棋盘格）"""
    for page in range(8):
        send_command(0xB0 + page)  # 设置页地址
        send_command(0x00)  # 设置列低 4 位
        send_command(0x10)  # 设置列高 4 位

        # 生成棋盘格数据
        data = []
        for col in range(128):
            if (page % 2 == 0 and col % 2 == 0) or (page % 2 == 1 and col % 2 == 1):
                data.append(0xFF)  # 点亮
            else:
                data.append(0x00)  # 熄灭

        send_data(data)

# 设置页和列地址的函数
def set_position(page, col):
    # 页地址范围：0 - 7
    if page < 0:
        page = 0
    if page > 7:
        page = 7
    # 列地址范围：0 - 127
    if col < 0:
        col = 0
    if col > 127:
        col = 127
    send_command(0xB0 + page)  # 设置页
    send_command(0x00 | (col & 0x0F))  # 设置列低 4 位
    send_command(0x10 | ((col >> 4) & 0x0F))  # 设置列高 4 位

# 显示文本函数（16x16 字模）
def show_text(text, page=0, col=0):
    """在指定页和列显示 ASCII 文本，16x16 字模"""
    font = {
            'A':[0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20],#A0
            
            'B':[0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00],#B1
            
            'C':[0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00],#C2
            
            'D':[0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00],#D3
            
            'E':[0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00],#E4
            
            'F':[0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00],#F5
                
            'H':[0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20],#H0
             
            
            'I':[0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00],#I1
             
            
            'J':[0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00],#J2
             
            
            'K':[0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00],#K3
             
            
            'L':[0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00],#L4
             
            
            'M':[0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x01,0x3E,0x01,0x3F,0x20,0x00],#M5
             
            
            'N':[0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00],#N6
             
            
            'O':[0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00],#O7
             
            
            'P':[0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00],#P8
             
            
            'Q':[0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x28,0x28,0x30,0x50,0x4F,0x00],#Q9
             
            
            'R':[0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20],#R10
             
            
            'S':[0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00],#S11
             
            
            'T':[0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00],#T12
             
            
            'U':[0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00],#U13
             
            
            'V':[0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00],#V14
             
            
            'W':[0x08,0xF8,0x00,0xF8,0x00,0xF8,0x08,0x00,0x00,0x03,0x3E,0x01,0x3E,0x03,0x00,0x00],#W15
             
            
            'X':[0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20],#X16
             
            
            'Y':[0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00],#Y17
             
            
            'Z':[0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00],#Z18
             
            
            '0':[0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00],#019
             
            
            '1':[0x00,0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00],#120
             
            
            '2':[0x00,0x70,0x08,0x08,0x08,0x08,0xF0,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00],#221
             
            
            '3':[0x00,0x30,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x18,0x20,0x21,0x21,0x22,0x1C,0x00],#322
             
            
            '4':[0x00,0x00,0x80,0x40,0x30,0xF8,0x00,0x00,0x00,0x06,0x05,0x24,0x24,0x3F,0x24,0x24],#423
             
            
            '5':[0x00,0xF8,0x88,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x20,0x20,0x20,0x11,0x0E,0x00],#524
             
            
            '6':[0x00,0xE0,0x10,0x88,0x88,0x90,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x20,0x1F,0x00],#625
             
            
            '7':[0x00,0x18,0x08,0x08,0x88,0x68,0x18,0x00,0x00,0x00,0x00,0x3E,0x01,0x00,0x00,0x00],#726
             
            
            '8':[0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00],#827
             
            
            '9':[0x00,0xF0,0x08,0x08,0x08,0x10,0xE0,0x00,0x00,0x01,0x12,0x22,0x22,0x11,0x0F,0x00],#928
             
            
            'G':[0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00],#G29
             
            
            'a':[0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x19,0x24,0x24,0x12,0x3F,0x20,0x00],#a30
             
            
            'b':[0x10,0xF0,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00],#b31
             
            
            'c':[0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00],#c32
             
            
            'd':[0x00,0x00,0x80,0x80,0x80,0x90,0xF0,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20],#d33
             
            'e':[0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x24,0x24,0x24,0x24,0x17,0x00],#e34
             
            'f':[0x00,0x80,0x80,0xE0,0x90,0x90,0x20,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00],#f35
             
            'g':[0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00],#g36
             
            'h':[0x10,0xF0,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20],#h37
             
            'i':[0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00],#i38
            
            'j':[0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00],#j39
            
            'k':[0x10,0xF0,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x06,0x29,0x30,0x20,0x00],#k40
            
            'l':[0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00],#l41
            
            'm':[0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F],#m42
            
            'n':[0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20],#n43
            
            'o':[0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00],#o44
            
            'p':[0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0x91,0x20,0x20,0x11,0x0E,0x00],#p45
            
            'q':[0x00,0x00,0x00,0x80,0x80,0x00,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0x91,0xFF,0x80],#q46
            
            'r':[0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00],#r47
            
            's':[0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00],#s48
            
            't':[0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x10,0x00],#t49
            
            'u':[0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20],#u50
            
            'v':[0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x03,0x0C,0x30,0x0C,0x03,0x00,0x00],#v51
            
            'w':[0x80,0x80,0x00,0x80,0x80,0x00,0x80,0x80,0x01,0x0E,0x30,0x0C,0x07,0x38,0x06,0x01],#w52
            
            'x':[0x00,0x80,0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x20,0x31,0x0E,0x2E,0x31,0x20,0x00],#x53
            
            'y':[0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x81,0x86,0x78,0x18,0x06,0x01,0x00],#y54
            
            'z':[0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00],#z55
            
            ':':[0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00],#:56
            
            '.':[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00],#.0

            ' ':[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],# 0

            '℃':[0x06,0x09,0x09,0xE6,0xF8,0x0C,0x04,0x02,0x02,0x02,0x02,0x02,0x04,0x1E,0x00,0x00,                
                0x00,0x00,0x00,0x07,0x1F,0x30,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x10,0x00,0x00],#℃57
                
            '温':[0x10,0x60,0x02,0x8C,0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
            0x04,0x04,0x7E,0x01,0x40,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00],#温0
            
            '度':[0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,
            0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00],#度1
            
            '按':[0x10,0x10,0x10,0xFF,0x90,0x20,0x98,0x88,0x88,0xE9,0x8E,0x88,0x88,0xA8,0x98,0x00,
                0x02,0x42,0x81,0x7F,0x00,0x00,0x80,0x84,0x4B,0x28,0x10,0x28,0x47,0x80,0x00,0x00],#按0


            '键':[0x40,0x30,0xEF,0x24,0x24,0x80,0xE4,0x9C,0x10,0x54,0x54,0xFF,0x54,0x7C,0x10,0x00,
                0x01,0x01,0x7F,0x21,0x51,0x26,0x18,0x27,0x44,0x45,0x45,0x5F,0x45,0x45,0x44,0x00],#键1


            '被':[0x08,0x08,0x89,0xEA,0x98,0x40,0x00,0xF8,0x88,0x88,0x88,0xFF,0x88,0xA8,0x18,0x00,
                0x02,0x01,0x00,0xFF,0x00,0x81,0x60,0x1F,0x80,0x43,0x2C,0x10,0x2C,0x43,0x80,0x00],#被2


            '下':[0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x02,0x02,0x42,0x82,0x02,0x02,0x02,0x02,0x00,
                0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x01,0x06,0x00,0x00,0x00]#下3


    }

    for char in text:
        if char in font:
            if char in {'温', '度', '℃','按','键','被','下'}:  # 判断是否为特定字符
                font_data = font[char]
                # 处理 16×16 字模
                set_position(page, col)
                send_data(font_data[:16])
                set_position(page + 1, col)
                send_data(font_data[16:])
                col += 16  # 列增加 16（16×16 字符宽度）
            else:
                # 处理 8×16 字模
                font_data = font[char]
                set_position(page, col)
                send_data(font_data[:8])
                set_position(page + 1, col)
                send_data(font_data[8:])
                col += 8  # 列增加 8（8×16 字符宽度）
    

# 主程序
# try:
#     # 初始化 OLED 显示
#     oled_init()
#     oled_clear()

#     # 测试显示
# #    test_pattern()
# #    time.sleep(2)

#     oled_clear()
#     show_text("I2C", 0, 0)  # 第 0 页，第 60 列开始显示
       
#     temp = 37
#     show_text("温度:", 2, 0)  # 显示“温度:”
#     temp_str = str(temp)  # 将数值转换为字符串
#     show_text(temp_str, 2, 16 * 2+8)  # 显示温度数值，“温度:”占 3 个字符宽度（16×3 列）
#     show_text("℃", 2, 16*2+8*(len(temp_str)+1))  # 显示℃符号，计算正确列位置    
    
#     show_text("HELLO", 4, 0)  # 第 0 页，第 60 列开始显示
#     show_text("world", 6, 0)  # 第 0 页，第 60 列开始显示
#     show_text("::::", 6, 40)  # 第 0 页，第 60 列开始显示
#     print("OLED 开始累加")
    
#     time.sleep(1) 
#     temp += 1
#     temp_str = str(temp)  # 将数值转换为字符串
#     show_text(temp_str, 2, 16 * 2+8)  # 显示温度数值，“温度:”占 3 个字符宽度（16×3 列）
    
#     time.sleep(1) 
#     temp += 1
#     temp_str = str(temp)  # 将数值转换为字符串
#     show_text(temp_str, 2, 16 * 2+8)  # 显示温度数值，“温度:”占 3 个字符宽度（16×3 列）

#     time.sleep(1) 
#     temp += 1
#     temp_str = str(temp)  # 将数值转换为字符串
#     show_text(temp_str, 2, 16 * 2+8)  # 显示温度数值，“温度:”占 3 个字符宽度（16×3 列）
        


# except Exception as e:
#     print(f"发生错误: {e}")
#     oled_clear()  # 尝试清屏